package com.sky.aspect;

import com.sky.annotation.AutoFill;
import com.sky.context.BaseContext;
import com.sky.enumeration.OperationType;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.time.LocalDateTime;


/**
 * 用于增强mapper添加，更新方法。完成公共字段的填充
 */
@Component
@Aspect
public class AutoFillAspect {

    /**
     * 对所有打上@AutoFill注解作前置增强，增强这些方法的参数
     * @param joinPoint
     */
    @Before("@annotation(com.sky.annotation.AutoFill)")
    public void autoFill(JoinPoint joinPoint) throws NoSuchFieldException, IllegalAccessException {

        //0、获得方法的参数:添加或者更新的方法参数只有一个，所以getArgs返回的数组里面只需要取第一个。
        Object arg = joinPoint.getArgs()[0];
        //1、获取方法签名
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        //2、根据方法签名获取方法method对象
        Method method = signature.getMethod();
        //3、根据method对象、获得方法身上的注解@AutoFill
        AutoFill annotation =method.getAnnotation(AutoFill.class);
        //4、根据注解的对象、获得它里面的value属性
        OperationType value = annotation.value();
        //5、判断是添加还是更新，区分是填充4个值还是2个值。
        if(value ==OperationType.INSERT){
            System.out.println("自动填充里"+method);
            //4个属性
            //获取到参数的字节码对象
            Class clazz = arg.getClass();

            Field f1 = clazz.getDeclaredField("createTime");
            Field f2 = clazz.getDeclaredField("updateTime");
            Field f3 = clazz.getDeclaredField("createUser");
            Field f4 = clazz.getDeclaredField("updateUser");

            //暴力反射
            f1.setAccessible(true);
            f2.setAccessible(true);
            f3.setAccessible(true);
            f4.setAccessible(true);

            f1.set(arg,LocalDateTime.now());
            f2.set(arg,LocalDateTime.now());
            f3.set(arg,BaseContext.getCurrentId());
            f4.set(arg,BaseContext.getCurrentId());

        }else{
            System.out.println("自动填充更新的属性"+method);
            //2个属性
            Class clazz = arg.getClass();
            Field f1 = clazz.getDeclaredField("updateTime");
            Field f2 = clazz.getDeclaredField("updateUser");
            //暴力反射
            f1.setAccessible(true);
            f2.setAccessible(true);

            f1.set(arg,LocalDateTime.now());
            f2.set(arg,BaseContext.getCurrentId());
        }
        //6、通过反射取得对应的4或者2个属性对象

        //7、通过反射直接给他们赋值


    }

}
